package io.github.iogogogo.commons.pdf;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.font.FontSet;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 根据template模板生成pdf，支持中文
 * 需要将模板文件放在classpath/templates下
 *
 * @author tao.zeng9@outlook.com
 * @since 2025/6/12 20:42
 */
@Slf4j
@Component
public class PdfGenerator {

    private final SpringTemplateEngine templateEngine;

    public PdfGenerator(SpringTemplateEngine templateEngine) {
        this.templateEngine = templateEngine;
    }

    public byte[] generatePdf(String templateName, Context context) throws Exception {
        // 渲染HTML模板
        String htmlContent = templateEngine.process(templateName, context);

        // 配置PDF转换器
        ConverterProperties props = new ConverterProperties();
        FontSet fontSet = new FontSet();

        // 加载字体（无 "classpath:" 前缀！）
        ClassPathResource resource = new ClassPathResource("static/simfang.ttf");
        try (InputStream inputStream = resource.getInputStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();) {
            byte[] bytes = IOUtils.toByteArray(inputStream);
            // 关键：加载中文字体文件路径，此种方式打包后加载路径为：BOOT-INF/classes/static/simfang.ttf，会出现FileNotFound异常
            // File fontFile = ResourceUtils.getFile("classpath:static/simfang.ttf");
            // 注册字体文件路径（支持所有样式：正常、粗体、斜体等）
            fontSet.addFont(bytes);
            log.debug("生成pdf字体加载成功（流模式）");

            // 创建 FontProvider 并绑定 FontSet
            FontProvider fontProvider = new FontProvider(fontSet);
            props.setFontProvider(fontProvider);
            // 执行HTML→PDF转换
            HtmlConverter.convertToPdf(htmlContent, outputStream, props);
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("生成pdf失败");
        }
    }
}
